home *** CD-ROM | disk | FTP | other *** search
- ; ***************************************************************************
- ; * *
- ; * MSCDEX.ASM *
- ; * *
- ; * C D - R O M Device Driver Hardware Independent Interface. *
- ; * *
- ; * This file defines the hardware independent interface to the valid CD-ROM*
- ; * device driver commands defined in the document "Microsoft MS-DOS CD-ROM *
- ; * Extensions Hardware-Dependent Device Driver Specification", *
- ; * #000080010-100-O00-1186. The implementation of a MSCDEX CD-ROM device *
- ; * driver will include this file verbatim. *
- ; * *
- ; * History: *
- ; * *
- ; * Created (v2.20) *
- ; * Fri Jun 22 1990 -by- Michael Edwards *
- ; * Modified (v2.20) *
- ; * 10/1/90 -by- JohnYG *
- ; * Final Release (v2.20) *
- ; * *
- ; * *
- ; ***************************************************************************
-
- include mscdex.inc
- include macros.mac
-
-
- public bcd2red
- public red2hsg
- public hsg2red
- public bcd2bin
-
- public DeviceHeader
- public units
- public very_end
-
- extrn cdrom_read : near
- extrn cdrom_prefetch : near
- extrn cdrom_seek : near
- extrn cdrom_play_audio : near
- extrn cdrom_stop_audio : near
- extrn cdrom_location_head : near
- extrn cdrom_audio_channel_info: near
- extrn cdrom_read_drive_bytes : near
- extrn cdrom_device_status : near
- extrn cdrom_volume_size : near
- extrn cdrom_media_changed : near
- extrn cdrom_audio_diskinfo : near
- extrn cdrom_audio_diskinfo : near
- extrn cdrom_audio_trackinfo : near
- extrn cdrom_audio_Qchannel : near
- extrn cdrom_audio_Subchannel : near
- extrn cdrom_upc_code : near
- extrn cdrom_audio_status_info : near
- extrn cdrom_eject : near
- extrn cdrom_lock_door : near
- extrn cdrom_reset_drive : near
- extrn cdrom_audio_channel_ctrl: near
- extrn cdrom_write_drive_ctrl : near
- extrn cdrom_close_tray : near
- extrn cdrom_input_flush : near
- extrn cdrom_input_flush : near
- extrn cdrom_device_open : near
- extrn cdrom_device_close : near
- extrn cdrom_current_loc : near
- extrn cdrom_drive_status : near
- extrn cdrom_audio_check : near
- extrn cdrom_init : near
-
- _TEXT segment byte public 'CODE'
- assume cs:_TEXT
-
- ;
- ; device drivers originate at 0 (not 100h)
- ;
- org 0
-
- very_top label byte
- ;
- ; First character Device header (must be at offset 0)
- ;
- DeviceHeader:
- dw -1, -1 ;pointer to next device
- dw 0c800h ;(character, IOCTL, Open/Close/RM)
- dw strategy ;strategy routine offset
- dw interrupt ;interrupt routine offset
- db '12345678' ;device name (must be 8 valid chars)
- dw 0 ;reserved
- db 0 ;drive letter
- units db 1 ;number of units
-
- RequestHeader:
- dd 0 ;strategy keeps request header ptr here
- ;
- ; Standard DOS device driver functions
- ;
- DriverFuncs:
- dw error ;*INIT (via far jmp from interrupt)
- dw error ; Media Check
- dw error ; Get BPB
- dw ioctl_input ;*IOCTL input
- dw error ; Input
- dw error ; Non-destructive Input
- dw error ; Input status
- dw input_flush ;*Input Flush (Hitachi does nothing)
- dw error ; Output
- dw error ; Output with verify
- dw error ; Output Status
- dw error ; Output Flush
- dw ioctl_output ;*IOCTL output
- dw device_open ;*Device Open
- dw device_close ;*Device Close
- dw error ; Removable Media
- dw error ; Output until Busy
- ;
- ; Extended CDROM device driver functions
- ;
- dw read_long ;*READ LONG
- dw error ; READ LONG NON-BLOCKING (Reserved)
- dw prefetch ;*READ LONG PREFETCH
- dw seek ;*SEEK
- dw play_audio ;+PLAY
- dw stop_audio ;+STOP PLAY
- dw error ; WRITE LONG
- dw error ; WRITE LONG VERIFY
- dw resume_audio ;+RESUME AUDIO
- ;
- ; IOCTL INPUT sub-functions
- ;
- IOCTLInput:
- dw return_address ; IOI_return_address
- dw location_head ; IOI_location_head
- dw error ; IOI_ioquery
- dw error ; IOI_err_stats
- dw audio_channel_info ; IOI_audio_info
- dw read_drive_bytes ; IOI_read_drive_bytes_bytes
- dw device_status ; IOI_device_statusus
- dw sector_size ; IOI_ret_sectsize
- dw volume_size ; IOI_ret_volsize
- dw media_changed ; IOI_media_changed
- dw audio_diskinfo ; IOI_audio_disk_info
- dw audio_trackinfo ; IOI_audio_track_info
- dw audio_Qchannel ; IOI_audio_qch_info
- dw audio_Subchannel ; IOO_Audio_Subinfo
- dw upc_code ; IOO_upc_code
- dw audio_status_info ; IOO_audio_status_info
- ;
- ; IOCTL OUTPUT sub-functions
- ;
- IOCTLOutput:
- dw eject ; IOO_eject_disc
- dw lock_door ; IOO_lock_door
- dw reset_drive ; IOO_reset_drive
- dw audio_channel_ctrl ; IOO_audio_channel_ctrl
- dw write_drive_ctrl ; IOO_write_drive_ctrl
- dw close_tray ; IOO_close_tray
-
- opens dw 0 ;number of unbalanced device open calls
- drive_num dw 0 ;drive operation is requested on
- audio_start dd 8 dup(0) ;last starting play audio location
- audio_end dd 8 dup(0) ;last ending play audio location
- play_mode db 8 dup(0) ;audio paused/playing flags
- init_done db 0 ;boolean whether device is init'd
-
-
- ;======================================================================
- ;
- ; strategy
- ;
- ; Device Strategy routine. Saves the pointer to the caller's request
- ; header structure for the subsequent call into interrupt below.
- ;
- ; Entry:
- ; es:bx - far ptr to the caller's request header.
- ;
- ; Exit:
- ; RequestHeader - far ptr to the caller's request header.
- ;
- ;======================================================================
- strategy proc far
-
- mov word ptr cs:RequestHeader.lo,bx
- mov word ptr cs:RequestHeader.hi,es
- ret
-
- strategy endp
-
-
- ;======================================================================
- ;
- ; interrupt
- ;
- ; Main entry point to the device interrupt handler.
- ;
- ; Entry:
- ; RequestHeader - far ptr to the caller's request header.
- ; (see MSCDEX.INC) for format of the request header)
- ;
- ;======================================================================
- interrupt proc far
-
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
- ;
- ; point ds:bx at the request header
- ;
- lds bx,dword ptr cs:RequestHeader
-
- mov al,[bx].rqh_unit ;al gets drive number
- cbw
- mov cs:drive_num,ax ;Save drive number
-
- mov si,offset DriverFuncs
- mov al,[bx].rqh_cmd ;get command
- cmp al,DVRQ_NCMD_MAX ;extended command?
- jbe ok_cmd ; nope
- ;
- ; must be extended cdrom device driver command, convert into index at
- ; end the normal cdrom device driver function table
- ;
- cmp al,DVRQ_ECMD_MIN
- jb @f
- sub al,(DVRQ_ECMD_MIN - DVRQ_NCMD_MAX - 1)
- cmp al,(DVRQ_NCMD_MAX + DVRQ_ECMD_MAX - DVRQ_ECMD_MIN + 1)
- jbe ok_cmd ; yes
- @@:
- jmp error ; nope, command out of range
-
- ok_cmd:
- cbw
- shl ax,1
- add si,ax
- or ax,ax ;init time?
- jz @f ; yes
- ; no, dispatch to command
- dispatch_to_command:
- jmp word ptr cs:[si]
- @@: ;being loaded from config.sys?
- mov al,1
- xchg cs:init_done,al
- or al,al
- jnz dispatch_to_command ; no, jmp to error
- jmp far ptr init ; yes, do init
-
-
- ;======================================================================
- ;
- ; read_long
- ;
- ; READ LONG, extended CD-ROM device driver routine to read sectors.
- ;
- ; Entry:
- ; ds:bx - far ptr to the request header.
- ;
- ;======================================================================
- read_long:
-
- WriteAux <read_long>
-
- call prepare_read_prefetch
-
- or cx,cx ;number of sectors to read
- jne @f
- mov ax,drverr_read_fault ;what? nothing to read!
- jmp short read_error
- @@:
- ;
- ; dl:ax - redbook address for read
- ; cx - number of sectors to read
- ; es:bx - transfer address for data
- ; dh - drive number (0 based)
- ; di - read mode (0 = cooked, 1 = raw)
- ;
- call cdrom_read ;ask the device dependent code to read
- jc read_error ;error occurred?
- jmp exit_not_busy ; nope
-
- read_error:
- jmp exit ; yep, status word's in ax
-
-
- ;======================================================================
- ;
- ; prefetch
- ;
- ; READ LONG PREFETCH, extended CD-ROM device driver routine to asynchronously
- ; read sectors into internal drive or driver controlled buffers.
- ;
- ; The cheap way to implement the prefetch command is with a seek since
- ; prefetching is considered advisory. If a drive, or the driver software,
- ; implement a "read-ahead" buffer, this entry point would initiate filling
- ; the buffer, in anticipation of a subsequent READ LONG command from the
- ; same location.
- ;
- ; Entry:
- ; ds:bx - far ptr to the caller's request header.
- ;
- ;======================================================================
- prefetch:
-
- WriteAux <prefetch>
-
- call prepare_read_prefetch
- ;
- ; dl:ax - redbook address for read
- ; cx - number of sectors to read
- ; es:bx - transfer address for data
- ; dh - drive number (0 based)
- ; di - read mode (0 = cooked, 1 = raw)
- ;
- call cdrom_prefetch
- jc @f ;error occurred?
- jmp exit_not_busy ; no, return success
- @@: jmp exit ; yep, status word's in ax
-
-
- ;======================================================================
- ;
- ; seek
- ;
- ; SEEK, extended CD-ROM device driver routine to asynchronously cause
- ; the drive head to seek to the passed location.
- ;
- ; Note if the drive, or driver, has control of any data buffers this
- ; command could be implemented as a READ operation. In this way the
- ; data at the passed location would be buffered (in anticipation of a
- ; subsequent read request), and the drive head would end up "waiting"
- ; at the position where its buffers had filled.
- ;
- ; Entry:
- ; ds:bx - far ptr to the caller's request header.
- ;
- ;======================================================================
- seek:
-
- WriteAux <seek>
-
- mov ax,(ERRBIT + DONEBIT + BUSYBIT + drverr_general_failure)
- call check_if_busy ;don't return if busy
- ;
- ; get sector to seek in dx:ax
- ;
- mov ax,word ptr rwl_sectno[si]
- mov dx,word ptr rwl_sectno[si+2]
-
- cmp rwl_addrmd[si],MODE_RED ;redbook addressing mode ??
- je seek_redbook ; yes
- cmp rwl_addrmd[si],MODE_HSG ; no, HSG addressing mode ??
- je seek_hsg ; yes
- mov ax,(ERRBIT + DONEBIT + drverr_unknown_command)
- jmp exit ; no, return we don't understand
-
- seek_redbook:
- call red2hsg
-
- seek_hsg:
- ;
- ; Setup to seek to the desired block number
- ;
- call hsg2red ;dx:ax is HSG logical sector number
- mov dh,byte ptr cs:drive_num;dl = drive number
- call clear_audio_flags
- ;
- ; dl:ax - redbook address for read
- ; dh - drive number (0 based)
- ;
- call cdrom_seek ;ask the device dependent code to seek
- jc @f ;error occurred?
- jmp exit_not_busy ; no, return success
- @@: jmp exit ; yep, status word's in ax
-
-
- ;======================================================================
- ;
- ; play_audio
- ;
- ; PLAY AUDIO, extended CD-ROM device driver routine to play the passed
- ; CD-Audio tracks.
- ;
- ; Note the busy bit in the request header must now indicate the drive
- ; is busy playing audio. Also the starting/ending play locations and
- ; the audio paused flag must be initialized for use in pausing/resuming
- ; audio and reporting through the Audio Status info IOCTL Input
- ; fuction.
- ;
- ; Entry:
- ; ds:bx - far ptr to the caller's request header.
- ;
- ;======================================================================
- play_audio:
-
- WriteAux <play_audio>
-
- mov ax,(ERRBIT + DONEBIT + BUSYBIT + drverr_general_failure)
- call check_if_busy ;don't return if busy
- ;
- ; get starting location from the PLAY command request header structure
- ;
- mov ax,wptr pl_start[si].lo
- mov dx,wptr pl_start[si].hi
- ;
- ; convert the starting address into hsg format if necessary
- ;
- cmp [si].pl_addrmd,MODE_RED
- je @f
- cmp [si].pl_addrmd,MODE_HSG
- je play_hsg
- ;
- ; don't understand requested play mode
- ;
- mov ax,(ERRBIT + DONEBIT + drverr_unknown_command)
- jmp exit
- @@:
- call red2hsg
-
- play_hsg:
- ;
- ; save the HSG starting logical sector number
- ;
- mov bp,bx
- shl bp,1
- shl bp,1
- mov wptr cs:audio_start[bp].lo,ax
- mov wptr cs:audio_start[bp].hi,dx
- mov di,ax
- mov cx,dx
- ;
- ; determine and save the ending HSG locical sector number
- ;
- add ax,wptr pl_num[si].lo ;get playing length
- adc dx,wptr pl_num[si].hi
- mov wptr cs:audio_end[bp].lo,ax
- mov wptr cs:audio_end[bp].hi,dx
-
- play_start:
- ;
- ; this is also an entry point from RESUME AUDIO
- ;
- ; dx:ax - audio ending HSG logical sector number
- ; cx:di - audio start HSG logical sector number
- ; bx - drive number
- ; bp - drive number * 4
- ;
- call cdrom_play_audio ;ask device dependent code to play
- jc @f ;was play successful?
- mov byte ptr cs:play_mode[bx],PLAY_TRUE ; yes
- jmp exit_busy
- @@: ; no
- mov byte ptr cs:play_mode[bx],PLAY_FALSE;reset playing mode flag
- xor cx,cx
- mov word ptr cs:audio_start[bp],cx ;clear start and end..
- mov word ptr cs:audio_start[bp+2],cx ;..locations
- mov word ptr cs:audio_end[bp],cx
- mov word ptr cs:audio_end[bp+2],cx
- jmp exit ;return error status in ax
-
-
- ;======================================================================
- ;
- ; stop_audio
- ;
- ; STOP AUDIO, extended CD-ROM device driver routine to pause or stop
- ; the CD-Audio tracks currently playing.
- ;
- ; Note the busy bit in the request header must now indicate the drive
- ; is no longer busy playing audio. Also the audio paused flag must be
- ; set if this is the first STOP AUDIO command received since the last PLAY
- ; AUDIO or RESUME AUDIO command. Otherwise (if this is the second
- ; STOP AUDIO command in a row) it must be cleared and the starting/ending
- ; play locations must be zeroed.
- ;
- ; Entry:
- ; ds:bx - far ptr to the caller's request header.
- ;
- ;======================================================================
- stop_audio:
-
- xor ax,ax ;return if busy
- call check_if_busy ;currently playing?
- pushf
- mov bp,bx ;bx = drive num
- shl bp,1 ;bp = drive num * 4
- shl bp,1
- popf
- jc stop_audio_pause ; yep
- jnc stop_audio_stop ; nope
-
- stop_audio_pause:
-
- WriteAux <pause_audio>
-
- ;
- ; this is the first STOP AUDIO command received since last PLAY or RESUME
- ; AUDIO command, so reset the start location to current location, and
- ; set the audio paused flag
- ;
- call get_current_loc ;get HSG logical sector at drive head
- jc stop_audio_stop
- mov word ptr cs:audio_start[bp],ax
- mov word ptr cs:audio_start[bp+2],dx
- ;
- ; make sure we havn't passed the ending location
- ;
- cmp dx,word ptr cs:audio_end[bp+2]
- ja stop_audio_stop
- jb @f
- cmp ax,word ptr cs:audio_end[bp]
- ja stop_audio_stop
- @@: mov byte ptr cs:play_mode[bx],PAUSE_TRUE
- ;
- ; tell the drive to stop playing audio. if desired this can actually be
- ; implemented as a command to pause the head at the current location, but
- ; at any rate the audio will be resumed with a play audio command which
- ; passes the starting and ending locations to play (see resume_audio).
- ;
- stop_audio_exit:
-
- ; bx - drive number to pause/stop audio on
- ;
- call cdrom_stop_audio
- jnc @f ;reset pause flag if error occurred
- mov byte ptr cs:play_mode[bx],PAUSE_FALSE
- @@: jmp exit_not_busy
-
- stop_audio_stop:
- ;
- ; the drive is not already playing audio so we need to REALLY stop audio by
- ; clearing the audio paused flag and zeroing the starting/ending locations
- ;
- WriteAux <stop_audio>
-
- xor ax,ax
- mov word ptr cs:audio_start[bp],ax
- mov word ptr cs:audio_start[bp+2],ax
- mov word ptr cs:audio_end[bp],ax
- mov word ptr cs:audio_end[bp+2],ax
- mov byte ptr cs:play_mode[bx],PAUSE_FALSE
- jmp short stop_audio_exit
-
-
- ;======================================================================
- ;
- ; resume_audio
- ;
- ; RESUME AUDIO, extended CD-ROM device driver routine to resume playing
- ; CD-Audio tracks previously paused (by calling STOP AUDIO).
- ;
- ; Note the busy bit in the request header must now indicate the drive
- ; is busy playing audio. Also the audio paused flag must be
- ; set if this is the first STOP AUDIO command received since the last PLAY
- ; AUDIO or RESUME AUDIO command. Otherwise (if this is the second
- ; STOP AUDIO command in a row) it must be cleared and the starting/ending
- ; play locations must be zeroed.
- ;
- ; Entry:
- ; ds:bx - far ptr to the caller's request header.
- ;
- ;======================================================================
- resume_audio:
-
- WriteAux <resume_audio>
-
- mov ax,(ERRBIT + DONEBIT + BUSYBIT + drverr_general_failure)
- call check_if_busy ;don't return if busy
- ;
- ; make sure audio has been previously paused before try resuming!
- ;
- cmp cs:play_mode[bx],PAUSE_TRUE
- mov ax,(ERRBIT + DONEBIT + drverr_general_failure)
- jne resume_error
- ;
- ; ask device dependent code if the drive is able to resume audio now
- ;
- call get_drive_status
- mov ax,(ERRBIT + DONEBIT + drverr_drive_not_ready)
- jc resume_error
- ;
- ; setup registers for entry into the play audio command:
- ;
- mov bp,bx
- shl bp,1
- shl bp,1
- mov dx,word ptr cs:audio_end[bp+2]
- mov ax,word ptr cs:audio_end[bp]
- mov cx,word ptr cs:audio_start[bp+2]
- mov di,word ptr cs:audio_start[bp]
- ;
- ; dx:ax - audio ending HSG logical sector number
- ; cx:di - audio start HSG logical sector number
- ; bx - drive number
- ; bp - drive number * 4
- ;
- jmp play_start
-
- resume_error:
- jmp exit ;return error status in ax
-
-
- ;======================================================================
- ;
- ; ioctl_input
- ;
- ; IOCTL INPUT, CD-ROM device driver routines to retrieve device information:
- ;
- ; - address of device header
- ; - location of head
- ; - error statistics
- ; - audio channel information
- ; - read drive bytes
- ; - device status
- ; - sector size
- ; - volume size
- ; - media changed
- ; - audio disk information
- ; - audio track information
- ; - audio Q-channel information
- ; - audio sub-channel information
- ; - audio status information
- ;
- ; Entry:
- ; ds:bx - far ptr to the caller's request header.
- ;
- ; Dispatch to IOCTL input subfunctions:
- ; es:di - application control block (xfer address) after command code
- ; bx - drive number
- ;
- ;======================================================================
- ioctl_input:
-
- mov si,offset IOCTLInput ;ioctl input subfunction table
- mov dl,IOI_cmd_max ;last ioctl input subfunction
-
- ioctl_dispatch:
- ;
- ; dl contains the 0-based value of last valid sub-function number
- ; si points to the function dispatcher table
- ;
- les di,ioctl_xfer[bx] ;application's transfer address
- mov al,es:[di] ;get the sub-function command code..
- inc di ;..and point just past it
- cmp al,dl ;out of bounds?
- jbe @f ; no
- jmp error ; yes
- @@:
- cbw
- shl ax,1
- add si,ax
- ;
- ; dispatch point to IOCTL INPUT/OUTPUT sub-functions
- ;
- mov bx,cs:drive_num
- jmp word ptr cs:[si] ;jump to the requested ioctl function
-
-
- ;======================================================================
- ;
- ; ioctl_output
- ;
- ; IOCTL OUTPUT, CD-ROM device driver routines relay for sending various
- ; commands to the drive to:
- ;
- ; - Eject Disk (open tray)
- ; - Lock/Unlock drive door
- ; - Reset drive
- ; - Audio Channel Control
- ; - Write device control string
- ; - Close tray
- ;
- ; Entry:
- ; ds:bx - far ptr to the caller's request header.
- ;
- ; Dispatch to IOCTL output subfunctions:
- ; es:di - application control block (xfer address) after command code
- ; bx - drive number
- ;
- ;======================================================================
- ioctl_output:
-
- mov si,offset IOCTLOutput ;function dispatcher for IOCTL Output
- mov dl,IOO_cmd_max ;number of IOCTL Output functions
- jmp short ioctl_dispatch ;go to ioctl function dispatcher
-
-
- ioctl_io_exit:
- ;
- ; generic successful IOCTL INPUT/OUTPUT exit point
- ;
- mov ax,(DONEBIT + BUSYBIT) ;don't return if busy
- call check_if_busy ;bx != reqhead but don't need si..
- jmp exit_not_busy ;..to point at the reqhead anyway
-
-
- ;============================================================
- ;
- ; IOCTL INPUT commands...
- ;
- ;============================================================
-
- ;----------------------------------------------------------------------
- ;
- ; return_address
- ;
- ; IOCTL INPUT sub-function #0.
- ;
- ; Return the address of the device header.
- ;
- ;----------------------------------------------------------------------
- return_address:
-
- WriteAux <ioctl input return address>
-
- mov word ptr es:[di].io_devaddr,offset DeviceHeader
- mov word ptr es:[di+2].io_devaddr,cs
- jmp short ioctl_io_exit
-
-
- ;----------------------------------------------------------------------
- ;
- ; location_head
- ;
- ; IOCTL INPUT sub-function #1
- ;
- ; Return the current location of the drive head.
- ;
- ;----------------------------------------------------------------------
- location_head:
-
- WriteAux <ioctl input location head>
-
- ; ask the device driver to report on current head location
- ;
- call cdrom_location_head ;preserves di
- ;
- ; if carry set
- ; then an error occurred and the status word is in ax
- ; else
- ; dx:ax = HSG logical sector address of the drive head
- ;
- jnc @f
- jmp exit
- @@:
- ;
- ; we've got it in HSG, but do they want it returned in redbook?
- ;
- cmp es:io_loc_mode[di],MODE_HSG
- je location_head_hsg
- cmp es:io_loc_mode[di],MODE_RED
- je @f
- jmp error ;don't understand the addressing mode
-
- location_head_hsg:
- call hsg2red
- @@:
- mov word ptr es:io_loc[di],ax
- mov word ptr es:io_loc[di+2],dx
- jmp ioctl_io_exit
-
-
- ;----------------------------------------------------------------------
- ;
- ; IOCTL INPUT sub-function #2
- ;
- ; This sub-function is currently reserved for future use.
- ;
- ;----------------------------------------------------------------------
-
-
- ;----------------------------------------------------------------------
- ;
- ; error_statistics
- ;
- ; IOCTL INPUT sub-function #3
- ;
- ; Report error statistics (currently not defined).
- ;
- ;----------------------------------------------------------------------
-
-
- ;----------------------------------------------------------------------
- ;
- ; audio_channel_info
- ;
- ; IOCTL INPUT sub-function #4
- ;
- ; Report current audio channel control settings. This will be the default
- ; arrangement of 1:1 input to output at full volume, otherwise it's whatever
- ; was last set by the Audio Channnel Control IOCTL Output subfunction #3.
- ;
- ; Note:
- ; - if volume settings are limited to ON/OFF, then FFh is on, 0 is off.
- ; - if the drive doesn't support quadrophonic then input channels 2 and 3
- ; are assigned to output channels 0 and 1 with 0 volume.
- ;
- ;----------------------------------------------------------------------
- audio_channel_info:
-
- WriteAux <ioctl input audio channel info>
-
- ; es:di - transfer area for audio channel info
- ; bx - drive num to report on
- ;
- call cdrom_audio_channel_info
- ;
- ; returns with the applications parameter block setup:
- ;
- ; es:[di+0] - current input channel set for output channel 0
- ; es:[di+1] - current volume set for output channel 0
- ; es:[di+2] - current input channel set for output channel 1
- ; es:[di+3] - current volume set for output channel 1
- ; es:[di+4] - current input channel set for output channel 2
- ; es:[di+5] - current volume set for output channel 2
- ; es:[di+6] - current input channel set for output channel 3
- ; es:[di+7] - current volume set for output channel 3
- ;
- jmp ioctl_io_exit
-
-
- ;----------------------------------------------------------------------
- ;
- ; read_drive_bytes
- ;
- ; IOCTL INPUT sub-function #5
- ;
- ; Read device dependent information. This routine is for accessing
- ; device specific features not addressed by the MSCDEX device driver spec.
- ;
- ;----------------------------------------------------------------------
- read_drive_bytes:
-
- WriteAux <ioctl input read drive bytes>
-
- ; bx - drive number
- ; es:di - 129 byte transfer address for drive specific data
- ;
- call cdrom_read_drive_bytes ;sets es:[di+0] to num bytes xfered
- jmp ioctl_io_exit
-
-
- ;----------------------------------------------------------------------
- ;
- ; device_status
- ;
- ; IOCTL INPUT sub-function #6
- ;
- ; Return 32 bits of drive status information:
- ;
- ; 13 12 11 10 9 8 7 6 5 4 3 2 1 0 BIT SET BIT CLEAR
- ; . | | | | | | | | | | | | | |
- ; 31 | | | | | | | | | | | | - door open | door closed
- ; | | | | | | | | | | | | | |
- ; | | | | | | | | | | | | --- door unlocked | door locked
- ; | | | | | | | | | | | | |
- ; | | | | | | | | | | | ----- cooked and raw mode | cooked mode only
- ; | | | | | | | | | | | |
- ; | | | | | | | | | | ------- read and write | read only
- ; | | | | | | | | | | |
- ; | | | | | | | | | --------- can play audio/video | data read only
- ; | | | | | | | | | |
- ; | | | | | | | | ----------- ISO-9660 interleave | no interleaving
- ; | | | | | | | | |
- ; | | | | | | | ------------- reserved |
- ; | | | | | | | |
- ; | | | | | | --------------- prefetching support | no prefetching
- ; | | | | | | |
- ; | | | | | ----------------- audio chnls configurable| not configurable
- ; | | | | | |
- ; | | | | ------------------- HSG and redbook addr | only HSG addr
- ; | | | | |
- ; | | | --------------------- reserved |
- ; | | | |
- ; | | ------------------------ no disc in drive | disc in drive
- ; | | |
- ; | --------------------------- P-W subchan. support | no subchan. spt.
- ; |
- ; ------------------------------ reserved (all bits clear)
- ;
- ;----------------------------------------------------------------------
- device_status:
-
- WriteAux <ioctl input device status>
-
- ; bx - drive number
- ;
- call cdrom_device_status
- ;
- ; returns status in dx:ax or carry set to indicate an error occurred
- ;
- jc @f
- ;
- ; set device status words in the application's space
- ;
- mov word ptr es:io_dev_params[di],ax
- mov word ptr es:io_dev_params[di+2],dx
- jmp ioctl_io_exit
- @@:
- mov ax,(ERRBIT + DONEBIT + drverr_drive_not_ready)
- jmp exit
-
-
-
- ;----------------------------------------------------------------------
- ;
- ; sector_size
- ;
- ; IOCTL INPUT sub-function #7
- ;
- ; Return CD-ROM sector size for the passed read mode. This must be
- ; 2048 for cooked, 2352 for raw.
- ;
- ;----------------------------------------------------------------------
- sector_size:
-
- WriteAux <ioctl input sector size>
-
- mov ax,2048 ;assume cooked mode
- cmp es:[di].io_sect_mode,IO_COOKED ;cooked assumption correct?
- je @f ; Yes
- mov ax,2352 ; nope, how about raw?
- cmp es:[di].io_sect_mode,IO_RAW
- je @f ; yep
- xor ax,ax ; nope, unknown I/O mode
- @@: mov es:[di].io_sect_size,ax
- jmp ioctl_io_exit
-
-
- ;----------------------------------------------------------------------
- ;
- ; volume_size
- ;
- ; IOCTL INPUT sub-function #8
- ;
- ; Return number of CD-ROM sectors available on the disc. This is the
- ; location of the lead out track in binary. For example a lead-out track
- ; at 31:14.63 would yield (31 * 60 * 75) + (14 * 75) + 63 = 140613.
- ;
- ;----------------------------------------------------------------------
- volume_size:
-
- WriteAux <ioctl input volume size>
-
- ; bx - drive number
- ;
- call cdrom_volume_size
- jc @f ;error getting size?
- mov word ptr es:[di].io_dev_params,ax
- mov word ptr es:[di+2].io_dev_params,dx
- jmp ioctl_io_exit
- @@:
- xor dx,dx ; yes
- mov word ptr es:[di].io_dev_params,dx
- mov word ptr es:[di+2].io_dev_params,dx
- jmp exit ;return status word in ax
-
-
-
- ;----------------------------------------------------------------------
- ;
- ; media_changed
- ;
- ; IOCTL INPUT sub-function #9
- ;
- ; Report whether the media has been changed. This vastly improves file i/o
- ; performance because MSCDEX can avoid re-reading the VTOC unless the disc
- ; has actually been changed.
- ;
- ; Exit:
- ; io_media byte = 1 - not changed
- ; io_media byte = -1 - changed
- ; io_media byte = 0 - can't determine if changed or not
- ;
- ;----------------------------------------------------------------------
- media_changed:
-
- WriteAux <ioctl input media changed>
-
- ; bx = drive num
- ;
- call cdrom_media_changed
- mov es:io_media[di],al ;set the media byte
- jc @f ;error occurred?
- jmp ioctl_io_exit
- @@:
- mov ax,(ERRBIT + DONEBIT + drverr_drive_not_ready)
- jmp exit ; yep, get outta here
-
-
-
-
- ;----------------------------------------------------------------------
- ;
- ; audio_diskinfo
- ;
- ; IOCTL INPUT sub-function #10
- ;
- ; Report the binary value of the lowest and highest track, and the redbook
- ; address of the lead-out track as recorded in the Q-channel of the
- ; lead-in track.
- ;
- ; In order to avoid interrupting audio to obtain this information it
- ; is recommended the necessary values are saved at disc intialization time.
- ;
- ;----------------------------------------------------------------------
- audio_diskinfo:
-
- WriteAux <ioctl input audio disk info>
-
- ; bx - drive num
- ; es:di - application buffer for disk info
- ;
- call cdrom_audio_diskinfo
- jc @f ;error occurred?
- jmp ioctl_io_exit
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; audio_trackinfo
- ;
- ; IOCTL INPUT sub-function #11
- ;
- ; Return the redbook address of the passed binary track number, and the
- ; track control information byte.
- ;
- ;----------------------------------------------------------------------
- audio_trackinfo:
-
- WriteAux <ioctl input audio track info>
-
- ; bx - drive num
- ; es:di - application buffer for track info
- ;
- call cdrom_audio_trackinfo
- jc @f ;error occurred?
- jmp ioctl_io_exit
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; audio_Qchannel
- ;
- ; IOCTL INPUT sub-function #12
- ;
- ; Return the current Q-channel address in redbook.
- ;
- ; Note the operation of this function *should not* change the current
- ; drive status, as it can be used to monitor the current head location.
- ; Therefore, it should be successful even if the drive is currently idle.
- ;
- ; Note the CONTROL/ADR and POINT/Index bytes are returned verbatim,
- ; and if ADR is 1, so is the address of the head location.
- ;
- ;
- ;----------------------------------------------------------------------
- audio_Qchannel:
-
- WriteAux <ioctl input audio Q channel>
-
- ; bx - drive num
- ; es:di - application buffer for disk info
- ;
- call cdrom_audio_Qchannel
- jc @f ;error occurred?
- jmp ioctl_io_exit
- @@: jmp exit ; yes, ax contains status
-
-
-
- ;----------------------------------------------------------------------
- ;
- ; audio_Subchannel
- ;
- ; IOCTL INPUT sub-function #13
- ;
- ; Returns the sub-channel information from the contiguous frames (sectors)
- ; requested starting at the passed redbook address. The sub-channels are
- ; not decoded, that is, P is the MSB and W is the LSB in each byte.
- ;
- ;
- ; The caller ensures the transfer address can hold 96 bytes/sector read.
- ; The new definition indicates that P-W can only be accessed during audio
- ; play requests.
- ;----------------------------------------------------------------------
- audio_Subchannel:
-
- WriteAux <ioctl input subchannel>
-
- ; bx - drive num
- ; es:di - application buffer for sub-channel bytes
- ;
- call cdrom_audio_Subchannel
- jc @f ;error occurred?
- jmp ioctl_io_exit
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; upc_code
- ;
- ; IOCTL INPUT sub-function #14
- ;
- ; Return the Universal Product Code of the disc. This is located in 10
- ; contiguous bytes of the Q-channel (ie., in one frame out of every 100),
- ; and identified with an ADR value of 2.
- ;
- ; Note, not all discs have one.
- ;
- ;----------------------------------------------------------------------
- upc_code:
-
- WriteAux <ioctl input UPC code>
-
- ; bx - drive num
- ; es:di - application buffer for UPC bytes
- ;
- call cdrom_upc_code
- jc @f ;error occurred?
- jmp ioctl_io_exit
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; audio_status_info
- ;
- ; IOCTL INPUT sub-function #15
- ;
- ; Return audio status information including whether audio is currently
- ; paused and the starting and ending location for the latest PLAY or
- ; RESUME AUDIO command.
- ;
- ;----------------------------------------------------------------------
- audio_status_info:
-
- WriteAux <ioctl input audio status info>
-
- ; bx - drive num
- ; es:di - application buffer for status info
- ;
- call cdrom_audio_status_info ;is the drive door open?
- jc @f ; yes
- mov al,cs:play_mode[bx] ; no
- test al,(PAUSE_TRUE or PLAY_TRUE)
- jz audio_status_info_null
- ;
- ; we're either paused or playing, in which case audio_start/end
- ; contain the starting and ending (disc relative) times to report in the
- ; audio status block (and play_mode has the paused flag)
- ;
- and ax,PAUSE_TRUE ;isolate paused bit and make it..
- shr ax,1 ;..the LSB of the audio status word
- mov word ptr es:io_audio_st_bit[di],ax
- shl bx,1
- shl bx,1
- mov ax,word ptr cs:audio_start[bx]
- mov dx,word ptr cs:audio_start[bx+2]
- call hsg2red
- mov word ptr es:io_audio_start[di],ax
- mov word ptr es:io_audio_start[di+2],dx
- mov ax,word ptr cs:audio_end[bx]
- mov dx,word ptr cs:audio_end[bx+2]
- call hsg2red
- mov word ptr es:io_audio_end[di],ax
- mov word ptr es:io_audio_end[di+2],dx
-
- audio_status_info_exit:
- jmp ioctl_io_exit
-
- @@:
- ;
- ; some sort of drive error or door is open, disable paused flag
- ;
- mov cs:play_mode[bx],PAUSE_FALSE
-
- audio_status_info_null:
- ;
- ; return not paused and NULL starting/ending locations
- ;
- xor ax,ax
- mov word ptr es:io_audio_st_bit[di],ax
- mov word ptr es:io_audio_start[di],ax
- mov word ptr es:io_audio_start[di+2],ax
- mov word ptr es:io_audio_end[di],ax
- mov word ptr es:io_audio_end[di+2],ax
- jmp short audio_status_info_exit
-
-
- ;============================================================
- ;
- ; IOCTL OUTPUT commands...
- ;
- ;============================================================
-
- ;----------------------------------------------------------------------
- ;
- ; eject
- ;
- ; IOCTL OUTPUT sub-function #0
- ;
- ; Unlock the drive door and eject the disc.
- ;
- ; Note that after successful completion of this command the status bit
- ; in the device status word should report the door as being open until the
- ; user has inserted a disc and closed the door (so the door open bit
- ; can be monitored until this has occurred).
- ;
- ;----------------------------------------------------------------------
- eject:
-
- WriteAux <ioctl output eject>
-
- ; bx - drive num
- ;
- call cdrom_audio_check ;busy with audio?
- jnc @f ; no
- call clear_audio_flags ; yes, clear pause/play flags
- @@:
- call cdrom_eject
- jc @f ;error occurred?
- call clear_audio_flags ;no, reset audio flags
- jmp ioctl_io_exit
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; lock_door
- ;
- ; IOCTL OUTPUT sub-function #1
- ;
- ; Unlock/lock the drive door.
- ;
- ;----------------------------------------------------------------------
- lock_door:
-
- WriteAux <ioctl output lock door>
-
- ; bx - drive num
- ; es:di - lock/unlock code byte (0 - unlock door, 1 - lock door)
- ;
- mov al,es:[di] ;pass user request in al
- cmp al,1
- ja lock_door_invalid_code
- call cdrom_lock_door
- jc @f
- jmp ioctl_io_exit
-
- lock_door_invalid_code:
- mov ax,(ERRBIT + DONEBIT + drverr_unknown_command)
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; reset_drive
- ;
- ; IOCTL OUTPUT sub-function #2
- ;
- ; Tell the drive to reset and re-initialize itself.
- ;
- ;----------------------------------------------------------------------
- reset_drive:
-
- WriteAux <ioctl output reset drive>
-
- ; bx - drive num
- ;
- call cdrom_audio_check ;busy with audio?
- mov ax,(ERRBIT + DONEBIT + BUSYBIT + drverr_general_failure)
- jc @f ; yes
- call cdrom_reset_drive ; no, ask for a reset
- jc @f ;error occurred resetting?
- call clear_audio_flags ; no, reset audio variables
- jmp ioctl_io_exit
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; audio_channel_ctrl
- ;
- ; IOCTL OUTPUT sub-function #3
- ;
- ; Control audio channel output.
- ;
- ; Drives that support audio volume control distribute the number of settings
- ; continuously across 256 values (eg. 16 settings become 0, 16, 32, ...).
- ;
- ; Drives than can't swap channels ignore channel swapping unless requested
- ; to play both channels in one, in which case the other is suppressed.
- ;
- ; Drives that don't support four audio channels should ignore setting
- ; specified for the second pair of channels.
- ;
- ;----------------------------------------------------------------------
- audio_channel_ctrl:
-
- WriteAux <ioctl output audio channel control>
-
- ; bx - drive num
- ; es:di - channel setting parameter block
- ;
- ; get the channel and volume settings
- ;
- mov cx,word ptr es:io_ch0_ich[di]
- mov dx,word ptr es:io_ch1_ich[di]
- mov si,word ptr es:io_ch2_ich[di]
- mov di,word ptr es:io_ch3_ich[di]
- ;
- ; parameters to cdrom_audio_channel_ctrl:
- ;
- ; bx - drive num
- ; cl - output channel for input channel 0
- ; ch - channel 0 volume setting
- ; dl - output channel for input channel 1
- ; dh - channel 1 volume setting
- ; si - lo byte = output channel for input channel 2
- ; hi byte = channel 2 volume
- ; di - lo byte = output channel for input channel 3
- ; hi byte = channel 3 volume
- ;
- call cdrom_audio_channel_ctrl
- jc @f ;error occurred?
- jmp ioctl_io_exit ; no
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; write_drive_ctrl
- ;
- ; IOCTL OUTPUT sub-function #4
- ;
- ; Write bytes directly to the CD-ROM drive.
- ;
- ; This routine is provided to allow device and/or driver dependent
- ; information (not addressed elsewhere in the MSCDEX device driver spec)
- ; to be sent by an application.
- ;
- ;----------------------------------------------------------------------
- write_drive_ctrl:
-
- WriteAux <ioctl output write drive bytes>
-
- ; bx - drive num
- ; es:di - channel setting parameter block
- ;
- call cdrom_write_drive_ctrl
- jc @f ;error occurred?
- jmp ioctl_io_exit ; no
- @@: jmp exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; close_tray
- ;
- ; IOCTL OUTPUT sub-function #5
- ;
- ; Close the drive door. This is the logical complement to the eject
- ; command (IOCTL OUTPUT sub-function #0)
- ;
- ;----------------------------------------------------------------------
- close_tray:
-
- WriteAux <ioctl output close tray>
-
- ; bx - drive num
- ;
- call cdrom_close_tray
- jc @f ;error occurred?
- jmp ioctl_io_exit ; no
- @@: jmp short exit ; yes, ax contains status
-
-
- ;======================================================================
- ;
- ; input_flush
- ;
- ; INPUT FLUSH, CD-ROM device driver routine requesting the device
- ; driver to free all input buffers and clear any pending requests.
- ;
- ;======================================================================
- input_flush:
-
- WriteAux <input flush>
-
- call cdrom_input_flush
- jc @f ;error occurred?
- jmp ioctl_io_exit ; no, return done/busy
- @@: jmp short exit ; yes, ax contains status
-
-
- ;======================================================================
- ;
- ; device_open
- ;
- ; DEVICE OPEN, CD-ROM device driver routine indicating to the device
- ; driver that an application is beginning to use it.
- ;
- ;======================================================================
- device_open:
-
- WriteAux <device open>
-
- inc cs:opens
- call cdrom_device_open
- jc @f ;error occurred?
- jmp ioctl_io_exit ; no, return done/busy
- @@: jmp short exit ; yes, ax contains status
-
-
- ;======================================================================
- ;
- ; device_close
- ;
- ; DEVICE CLOSE, CD-ROM device driver routine indicating to the device
- ; driver that an application is through using it.
- ;
- ;======================================================================
- device_close:
-
- WriteAux <device close>
-
- dec cs:opens
- call cdrom_device_close
- jc @f ;error occurred?
- jmp ioctl_io_exit ; no, return done/busy
- @@: jmp short exit ; yes, ax contains status
-
-
- ;----------------------------------------------------------------------
- ;
- ; Exit points.
- ;
- ;----------------------------------------------------------------------
-
- error:
- ;
- ; Exit indicating unknown command error
- ;
- mov ax,(ERRBIT + DONEBIT + drverr_unknown_command)
- jmp short exit
-
-
- exit_busy:
- ;
- ; Exit indicating no errors and audio is playing
- ;
- mov ax,(DONEBIT + BUSYBIT)
- jmp short exit
-
-
- exit_not_busy:
- ;
- ; Exit indicating no errors and audio is not playing
- ;
- mov ax,DONEBIT
-
- exit:
- ;
- ; Exit and poke the status word into the request header.
- ; This is always the final exit point.
- ;
- lds bx,dword ptr cs:RequestHeader
- mov [bx].rqh_status,ax
-
- exit_init:
- ;
- ; exit point from INIT
- ;
- pop es
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
- interrupt endp
-
-
-
- ;***************************************************************
- ;
- ; Various helper functions
- ;
- ;***************************************************************
-
-
-
- ;---------------------------------------------------------------
- ;
- ; prepare_read_prefetch
- ;
- ; Sets up registers for read_long() and prefetch().
- ;
- ; Entry:
- ; ds:bx - far ptr to the request header.
- ;
- ; Exit:
- ; if busy with audio
- ; exits device driver
- ; else
- ; dl:ax - redbook address for read
- ; cx - number of sectors to read
- ; es:bx - transfer address for data
- ; dh - drive number (0 based)
- ; di - read mode (0 = cooked, 1 = raw)
- ; audio paused/playing flag cleared
- ;
- ;
- ;---------------------------------------------------------------
- prepare_read_prefetch proc near
-
- mov ax,(ERRBIT + DONEBIT + BUSYBIT + drverr_general_failure)
- call check_if_busy ;don't return if busy
- ;
- ; Determine whether cooked or raw mode is selected
- ;
- xor ax,ax ;assume is cooked mode I/O (ax = 0)
- cmp [si].rwl_mode,IO_COOKED ;cooked mode I/O?
- je @f ; yes
- ; no
- inc ax ;assume raw mode I/O (ax = 1)
- cmp [si].rwl_mode,IO_RAW ;raw mode I/O?
- je @f ; yes
- mov ax,(ERRBIT + DONEBIT + drverr_unknown_command)
- jmp exit ; no, illegal mode for I/O
- @@:
- mov di,ax ;save read mode for below
- ;
- ; Initialize dx:ax to the desired block number
- ;
- mov ax,word ptr [si].rwl_sectno.lo
- mov dx,word ptr [si].rwl_sectno.hi
-
- cmp [si].rwl_addrmd,MODE_RED;already in redbook addressing mode?
- je @f ; yes
- call hsg2red ; no, HSG logical sector --> redbook
- @@:
- mov cx,[si].rwl_nsects ;bx = Number of blocks to read
- les bx,[si].rwl_xfer ;es:bx -> buffer
- mov dh,byte ptr cs:drive_num
- call clear_audio_flags
- ret
-
- prepare_read_prefetch endp
-
-
- ;---------------------------------------------------------------
- ;
- ; clear_audio_flags
- ;
- ; Resets the paused flag for the drive number passed in bx.
- ;
- ;---------------------------------------------------------------
- clear_audio_flags proc near
-
- push bx
- mov bx,cs:drive_num
- mov cs:play_mode[bx],PAUSE_FALSE
- pop bx
- ret
-
- clear_audio_flags endp
-
-
- ;---------------------------------------------------------------
- ;
- ; get_current_loc
- ;
- ; Return the current location of the drive head as a HSG sector address.
- ; This must be implemented using the Q-channel since the caller must
- ; be able to expect the successful operation of this routine will not
- ; interrupt audio playing.
- ;
- ; Entry:
- ; bx - drive number
- ;
- ; Exit:
- ; trashes bp,cx
- ; Carry set - an error occurred
- ; Carry clear - dx:ax = current HSG logical sector location of drive head.
- ;
- ;---------------------------------------------------------------
- get_current_loc proc near
-
- call cdrom_current_loc ;pass drive number in di
- ret
-
- get_current_loc endp
-
-
- ;---------------------------------------------------------------
- ;
- ; get_drive_status
- ;
- ; Return status of the drive.
- ;
- ; Entry:
- ; bx = drive num
- ; Exit:
- ; trashes ax,dx
- ; carry set -> drive is busy not ready error
- ;
- ;---------------------------------------------------------------
- get_drive_status proc near
-
- call cdrom_drive_status
- jc @f
- mov cs:play_mode[di],PAUSE_FALSE
- @@: ret
-
- get_drive_status endp
-
-
-
- ;----------------------------------------------------------------------
- ;
- ; check_if_busy
- ;
- ; This is the preamble to just about every routine. It points si to the
- ; request header offset and checks if the drive's playing audio. If not
- ; it returns with the carry flag clear, otherwise it will return with the
- ; carry flag set, or exit the driver, as indicated by ax upon entry.
- ;
- ; Entry:
- ; es:bx - ptr to request header
- ; ax - if 0 return to caller on error
- ; if !0 exit driver using ax for the status word on error
- ;
- ; Exit:
- ; bx - drive number
- ; si - request header offset
- ; carry clear if not busy
- ; carry set if busy (returns to caller or exits driver)
- ;
- ;----------------------------------------------------------------------
- check_if_busy proc near
-
- mov si,bx ;use the request header in si
- mov bx,cs:drive_num ;do we think we're playing audio?
- cmp cs:play_mode[bx],PLAY_TRUE
- clc
- je @f ; yes, make sure the drive agrees
- ret ; no, tell 'em we're not busy
- @@:
- push ax ;save status word for if jmp to exit
- call cdrom_audio_check
- pop ax
- jc @f
- mov cs:play_mode[bx],PLAY_FALSE
- ret
- @@:
- ;
- ; we think we're busy with audio, and sure enough, the drive agrees
- ;
- or ax,ax ;*** EXIT DRIVER ?
- jnz @f ; yes, ax = status word
- stc ; no, return to caller
- ret
- @@:
- pop bx ;skip return address
- jmp exit ;EXIT DRIVER
-
- check_if_busy endp
-
-
- ;----------------------------------------------------------------------
- ;
- ; bcd2bin
- ;
- ; Convert BCD to binary representation checking for invalid BCD format.
- ;
- ; Entry:
- ; al = BCD value (0-99).
- ;
- ; Exit:
- ; al = binary value (0-63h)
- ;
- ;----------------------------------------------------------------------
- bcd2bin proc near
-
- push bx
- push cx
- mov bl,al
- mov ah,al ; bl = ah = BCD value to error check
- and bl,0fh
- cmp bl,09h
- ja bad_bcd
- and ah,0f0h
- cmp ah,090h
- ja bad_bcd
- call _bcd2bin
- clc
- @@:
- xor ah,ah
- pop cx
- pop bx
- ret
- bad_bcd:
- stc
- jmp short @b
-
- bcd2bin endp
-
-
- ;----------------------------------------------------------------------
- ;
- ; _bcd2bin
- ;
- ; Convert BCD to binary.
- ;
- ; Entry:
- ; al = BCD value (0-99).
- ;
- ; Exit:
- ; al = binary value (0-63h)
- ; cx = trashed
- ;
- ;----------------------------------------------------------------------
- _bcd2bin proc near
-
- mov ch,al
- mov cl,4
- shr al,cl
- mov cl,10
- mul cl
- and ch,0fh
- add al,ch
- ret
-
- _bcd2bin endp
-
-
- ;----------------------------------------------------------------------
- ;
- ; bcd2red
- ;
- ; Converts each of the three bytes of the passed redbook address
- ; from BCD to binary representation.
- ;
- ; Entry:
- ; dh - 0
- ; dl - BCD min
- ; ah - BCD sec
- ; al - BCD frame
- ;
- ; Exit:
- ; dh - 0
- ; dl - binary min
- ; ah - binary sec
- ; al - binary frame
- ;
- ;----------------------------------------------------------------------
- bcd2red proc near
-
- push cx
- mov cx,ax
- xor ah,ah ; al = frame
- call bcd2bin
- mov cl,al
- mov al,ch ; al = sec
- call bcd2bin
- mov ch,al ; cx = sec,,frame
- mov al,dl ; al = min
- call bcd2bin
- mov dx,ax ; dl = min
- mov ax,cx
- pop cx
- ret
-
- bcd2red endp
-
-
- ;----------------------------------------------------------------------
- ;
- ; red2hsg
- ;
- ; Converts the passed (binary) redbook address into an HSG address.
- ;
- ; Entry:
- ; dh - 0
- ; dl - binary min
- ; ah - binary sec
- ; al - binary frame
- ;
- ; Exit:
- ; dx:ax contains HSG address (pure binary frame number less lead-in).
- ;
- ;----------------------------------------------------------------------
- red2hsg proc near
-
- push bx
- mov bx,ax ;save (sec:frame)
- mov al,dl ;al = min
- mov cl,60
- mul cl ;ax = min*60
- add al,bh
- adc ah,0 ;ax = min*60 + sec
- mov cx,75
- mul cx ;dx:ax = (min*60 + sec)*75
- xor bh,bh
- add ax,bx
- adc dx,0 ;dx:ax = (min*60 + sec)*75 + frame
- sub ax,150
- sbb dx,0 ;dx:ax = HSG address
- pop bx
- ret
-
- red2hsg endp
-
-
- ;----------------------------------------------------------------------
- ;
- ; hsg2red
- ;
- ; Converts passed HSG address into redbook address.
- ;
- ; Entry:
- ; dx:ax contains HSG address (logical sector number less lead-in area).
- ;
- ; Exit:
- ; dh - 0
- ; dl - binary min
- ; ah - binary sec
- ; al - binary frame
- ;
- ;----------------------------------------------------------------------
- hsg2red proc near
-
- push cx
- add ax,150 ;Add lead-in area
- adc dx,0
- mov cx,60*75
- div cx ;ax = minutes, dx = fraction of minutes
- xchg dx,ax ;dx = minutes
- mov cl,75
- div cl ;al = seconds, ah = frames
- xchg ah,al ;ah = seconds, al = frames
- pop cx
- ret
-
- hsg2red endp
-
-
- _TEXT ends
-
- ;***************************************************************
- ;
- ; resident code/data ends here, note this module should be first
- ; in the link (to start at an offset address of 0)
- ;
- ;
- ; code/data below here is for init time only
- ;
- ;***************************************************************
-
- _LAST segment para public 'last'
- assume cs:_LAST
-
- very_end label byte
-
- ;foobar macro y
- ;if2
- ; %out Resident size of driver is y
- ;endif
- ;endm
- ;
- ;foobar %(offset very_end)
-
-
- ;======================================================================
- ;
- ; init
- ;
- ; INIT, CD-ROM device driver routine to initialize the driver.
- ;
- ; This is the only device driver call coming directly from DOS, and is
- ; only made once. init should initialize certain fields in the request
- ; header:
- ;
- ; - Set init_units and init_devno to 0 since DOS views this as a character
- ; device (MSCDEX makes its own determination of the number of units through
- ; the device header).
- ;
- ; - Return the address of the end of the resident code/data section in
- ; init_endaddr. Code/data after this pointer is discarded.
- ;
- ; - Parse the CONFIG.SYS line after the '=' character (pointed to by
- ; init_bpbarr) for the device name and fill in the dev_name field in
- ; the device header making sure it is a legal 8-character filename
- ; (padded out to 8 characters with spaces if necessary).
- ;
- ; Entry:
- ; ds:bx - far ptr to the request header
- ; InitHeader struc
- ;
- ; init_rqh db size Request_Hdr dup (?)
- ; init_units db ?
- ; init_endaddr dd ?
- ; init_bpbarr dd ?
- ; init_devno db ?
- ;
- ; InitHeader ends
- ;
- ;======================================================================
-
- init proc far
-
- call cdrom_init
- jmp far ptr exit_init
-
- init endp
-
- _LAST ends
-
- ifdef DEBUG
-
- public very_top
- public DriverFuncs
- public IOCTLInput
- public IOCTLOutput
-
- public strategy
- public interrupt
- public read_long
- public prefetch
- public seek
- public play_audio
- public stop_audio
- public resume_audio
- public ioctl_output
- public ioctl_input
- public return_address
- public audio_channel_info
- public location_head
- public read_drive_bytes
- public device_status
- public sector_size
- public volume_size
- public media_changed
- public audio_diskinfo
- public audio_trackinfo
- public audio_Qchannel
- public upc_code
- public audio_status_info
- public eject
- public lock_door
- public reset_drive
- public audio_channel_ctrl
- public write_drive_ctrl
- public close_tray
- public input_flush
- public device_open
- public device_close
-
- endif ;DEBUG
-
- end
-
-